package com.andnnl.pool.user;

import com.andnnl.pool.Msg;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentLinkedQueue;

/**
 * 2级优先级用户消息，用在只有2个级别的消息
 * Created by chenss on 2021/6/23.
 */
public class TwoUser<T> extends AbsUser<T> {
    private final ConcurrentLinkedQueue<Msg<T>> queueFast = new ConcurrentLinkedQueue<>();//用户多的情况下，用Linked，省内存
    private final ConcurrentLinkedQueue<Msg<T>> queue = new ConcurrentLinkedQueue<>();//用户多的情况下，用Linked，省内存

    public TwoUser(String name) {
        this.name = name;
    }

    public TwoUser(String name, int batchSize) {
        this.name = name;
        this.batchSize = batchSize;
    }

    @Override
    public List<Msg<T>> takeMsg() {
        List<Msg<T>> list = new ArrayList<>();
        //忽略处理时，返回空
        if (isPause()) {
            return list;
        }
        int i = 0;
        while (i++ < batchSize) {
            Msg<T> m = queueFast.poll();//先从优先队列取
            if (m == null) {
                m = queue.poll();//再从队列取
                if (m == null) {
                    break;
                }
            }
            dataSize.addAndGet(-m.getDataSize());//累计总的dataSize
            list.add(m);
        }
        return list;
    }

    @Override
    public boolean isAllEmpty() {
        return queue.isEmpty() && queueFast.isEmpty();
    }

    @Override
    public void addMsg(Msg<T> msg) {
        msg.setUser(this);
        dataSize.addAndGet(msg.getDataSize());//累计总的dataSize
        if (msg.getPriority() > 0) {
            queueFast.add(msg);//把优先消息加进用户消息队列
        } else {
            queue.add(msg);
        }
    }


    public ConcurrentLinkedQueue<Msg<T>> getQueue() {
        return queue;
    }

    public ConcurrentLinkedQueue<Msg<T>> getQueueFast() {
        return queueFast;
    }

    @Override
    public int getTotalSize() {
        return queue.size() + queueFast.size();
    }

}
